#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/signal.h>

MODULE_LICENSE("Dual BSD/GPL");

#define PE0 128


// Warning!!: don't know what this for....
struct Gpioirq {
} gpioirq;

int irqnum = 0;

// request irq success or not
int irqsuccess = 0;

irqreturn_t gpioirq_isr(int irq, void* data)
{
	printk("got a PE0 interrupt\n");
	return IRQ_HANDLED;
}

static int __init gpioirq_init(void)
{
	int ret;

	// request gpio PE0
	if(0 != gpio_request(PE0, "PE0 gpio")) {
		printk(KERN_ALERT "Can't request PE0 for use\n");
	}

	irqnum = gpio_to_irq(PE0);
	printk(KERN_ALERT "Get PE0 irq num is %d\n", irqnum);

	// shared irq can't let last parameter void* dev_id as NULL
	if(0 != (ret = request_irq(irqnum, &gpioirq_isr, IRQF_TRIGGER_RISING | IRQF_SHARED, "gpioirq", &gpioirq))) {
		printk("request_irq failed ret value is %d!!, nr_irqs is %d\n", ret, NR_IRQS);
		if(EINVAL == -ret) {
			printk("irq error is -INVAL\n");
		} else if(EBUSY == -ret) {
			printk("irq error is -EBUSY\n");
		}
	} else {
		irqsuccess = 1;
	}


	return 0;
}

static void __exit gpioirq_exit(void)
{
	if(irqsuccess)
		free_irq(irqnum, &gpioirq);
	gpio_free(PE0);
	printk(KERN_ALERT "gpioirq_exit\n");
}

module_init(gpioirq_init);
module_exit(gpioirq_exit);
